package tcln.gxtx.client.widget.form;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import tcln.gxtx.client.utils.collection.GwtCollectionUtils;
import tcln.gxtx.client.widget.form.model.SimpleComboBoxModel;

/**
 * @param <E>
 *            Enum value type.
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 */
public class EnumComboBox<E extends Enum<?>> extends SimpleComboBox<E> {

    /**
     * Constructs this widget with an empty dropdown list.
     */
    public EnumComboBox() {
        super();
    }

    /**
     * Constructs this combobox from initial enum values.
     * 
     * @param values
     */
    public EnumComboBox(List<E> values) {
        setEnumValues(values);
    }

    /**
     * Constructs this combobox from initial enum values.
     * 
     * @param values
     */
    public EnumComboBox(E... values) {
        setEnumValues(Arrays.asList(values));
    }

    /**
     * Sets enum values for this combobox. Previous values will be cleared.
     * 
     * @param values
     */
    public void setEnumValues(List<E> values) {
        setValues(createModels(values));
    }

    /**
     * Returns current enum values stored in this widget.
     * 
     * @return the {@link #enumValues}.
     */
    public List<E> getEnumValues() {
        List<E> values = new ArrayList<E>(store.getCount());
        for (SimpleComboBoxModel<E> m : store.getModels()) {
            values.add(m.getId());
        }
        return values;
    }

    /**
     * Returns the selected enum value.
     * 
     * @return
     */
    public E getEnumValue() {
        SimpleComboBoxModel<E> model = getValue();
        return model != null ? model.getId() : null;
    }

    /**
     * Selects a value in this combobox.
     * 
     * @param enumValue
     *            Enum value of the item to be selected. If it's <code>null</code>, no item is selected.
     */
    public void select(E enumValue) {
        SimpleComboBoxModel<E> selectedModel = null;

        if (enumValue != null && store.getCount() > 0) {
            for (SimpleComboBoxModel<E> m : store.getModels()) {
                if (m.getValue().equals(enumValue.name())) {
                    selectedModel = m;
                    break;
                }
            }
        }

        if (selectedModel != null) {
            setValue(selectedModel);
        } else {
            deselectAll();
        }
    }

    private List<SimpleComboBoxModel<E>> createModels(List<E> values) {
        List<SimpleComboBoxModel<E>> results = new ArrayList<SimpleComboBoxModel<E>>(GwtCollectionUtils.size(values));
        for (E e : values) {
            SimpleComboBoxModel<E> m = new SimpleComboBoxModel<E>();
            m.setId(e);
            m.setValue(e.name()); // TODO LNT [Aug 22, 2010]: support i18n
            results.add(m);
        }
        return results;
    }
}
